﻿using Kinlo.Entitys;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using UIWindows.GlobalStatics;
using UIWindows.Services.Context;
using UIWindows.Tools.Helper;
using XingLucifer.Devices;
using XingLucifer.IBase.Enums;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolTip;

namespace UIWindows.Services.Handle
{
    [Attributes.TaskClassAttribute(TaskTypes.前称重)]
    public class BeforeWeighing : ServierBase
    {

        private volatile int _weighingNG = 0;
        public BeforeWeighing(DeviceConfigStatic deviceConfig, SystemConfigStatic systemConfig, UserConfigStatic userConfig, ParameterStatic parameterStatic, TemporaryStatic temporaryStatic, HomeStatic homeStatic, MesParameterStatic mesParameterStatic) :
            base(deviceConfig, systemConfig, userConfig, parameterStatic, temporaryStatic, homeStatic, mesParameterStatic)
        {
        }

        public override Task Handle(DataContext context)
        {
            if (!ClearSignal(context)) { return Task.CompletedTask; }
            try
            {
                _weighingNG = 0;
                var plc = _deviceConfig.DeviceList.FirstOrDefault(x => x.ServiceName == context.ServiceName && x.TaskType == TaskTypes.扫描信号).Communication as OmronCIP;
                DateTime weighing_time = DateTime.Now;
                var erinnerungen = ReadErinnerungen(plc, context.Address_Struct, context.Struct_Length, _systemConfig.IAddress.Erinnerungen_BeforeWeighing, context.AddressingMethod);
                if (erinnerungen.Item1)
                {
                    $"==>>{context.TaskType}<<==\r\n收到启动信号，没收到电池记忆，请联系电气工程师！！！".MessageDialogs(MessageLevelType.错误, false, Enums.PopUpTypes.Global);
                    return base.Handle(context);
                }
                RunLog($"记忆ID：{string.Join(";", erinnerungen.Item2.Select(x => x.SnowflakeId))}");
                bool alarm = false;
                Parallel.ForEach(erinnerungen.Item2, battery =>
                {
                    Models.Devices.DeviceClientModel? device = _deviceConfig.DeviceList.FirstOrDefault(x => x.ServiceName == context.ServiceName && x.TaskType == context.TaskType
                    && x.DeviceType == context.DeviceType && x.Index == battery.Index);
                    if (device == null)
                    {
                        RunLog($"找不到[{battery.Index}]号设备", MessageLevelType.错误);
                        WriteResult("", ResultTypes.不合格, plc, battery.Address_Struct, context);
                        return;
                    }
                    double? weiging = default;
                    if (battery.SnowflakeId == -1)
                    {
                        weiging = GetWeiging(device, "点检");
                        RunLog($"-[{battery.Index}] 点检重量：{weiging} g");
                        if (weiging == null)
                        {
                            _homeStatic.AddBeforeWeighingBattery("-1", ResultTypes.不合格, weighing_time, 0, battery.Index, null);
                            WriteResult("", ResultTypes.不合格, plc, battery.Address_Struct, context);
                            return;
                        }
                        _homeStatic.AddBeforeWeighingBattery("-1", ResultTypes.合格, weighing_time, (double)weiging, battery.Index, null);
                        WriteResult("", (weiging >= _parameterStatic.RangeParameter.SpotCheck_WeighingDown && weiging <= _parameterStatic.RangeParameter.SpotCheck_WeighingUp) ? ResultTypes.合格 : ResultTypes.不合格, plc, battery.Address_Struct, context);
                        return;
                    }
                    DateTime dateTime = DateTime.Now;
                    ProductionData? entity = _temporaryStatic.EntityCache.FirstOrDefault(x => x.SnowflakeId == battery.SnowflakeId);
                    //ProductionData? entity = _temporaryStatic.EntityCache.FirstOrDefault(x => x.SnowflakeId == battery.SnowflakeId);
                    if (entity == null)
                    {
                        RunLog($"-[{battery.Index}] 实体缓存查询不到==>[{battery.SnowflakeId}]，转到数据库查询");
                        entity = dateTime.GetEntity(context.TaskType, battery.SnowflakeId, DBSuffix);
                    }
                    else
                    {
                        ProductionData.Meta.TableName = entity.Items["TableName"].ToString();
                    }
                    if (entity == null)
                    {
                        RunLog($"-[{battery.Index}] 数据库找不到ID为：{battery.SnowflakeId}");
                        WriteResult("", ResultTypes.数据库找不到电池, plc, battery.Address_Struct, context);
                        return;
                    }
                    RunLog($"-[{battery.Index}] ID：[{battery.SnowflakeId}] 条码：[{entity.BarCode}]");
                    entity.TimeFormerWeighing = weighing_time.GetJSTimeUtc();
                    entity.LocationFormerWeighing = battery.Index;


                    //entity.RangeForeweigh = $"{_parameterStatic.RangeParameter.WeighBeforeDown}-{_parameterStatic.RangeParameter.WeighBeforeUp}";
                    //entity.RangeFluidRate = $"{_parameterStatic.RangeParameter.QuantitativeDown}-{_parameterStatic.RangeParameter.Quantitative}-{_parameterStatic.RangeParameter.QuantitativeUp}";

                    entity.RangeElectrodes = $"{_parameterStatic.RangeParameter.ElectrodesDown}={_parameterStatic.RangeParameter.ElectrodesUP}";
                    entity.RangeAfterWeighing = $"{_parameterStatic.RangeParameter.WeighAfterDown}-{_parameterStatic.RangeParameter.WeighAfterUp}";
                    entity.RangeForeweigh = $"{_parameterStatic.RangeParameter.WeighBeforeDown}-{_parameterStatic.RangeParameter.WeighBeforeUp}";
                    entity.RangeFluidRate = $"{_parameterStatic.RangeParameter.QuantitativeDown}-{_parameterStatic.RangeParameter.Quantitative}-{_parameterStatic.RangeParameter.QuantitativeUp}";


                    RunLog($"{entity.BarCode}：前称重范围：{entity.RangeForeweigh}");
                    //if (entity.FormerWeighing > 20 && entity.FormerWeighing > _parameterStatic.RangeParameter.WeighBeforeDown)
                    //{
                    //    //if (!WriteInjectionVolume((float)entity.TargetInjectionVolume, plc, battery.Address_Struct, context))
                    //    //{
                    //    //    entity.ResultFormerWeighing = ResultTypes.注液量写入失败;
                    //    //}
                    //    //说明已经称过重量了
                    //    WriteResult(entity.BarCode, entity.ResultFormerWeighing, plc, battery.Address_Struct, context);
                    //    _homeStatic.AddBeforeWeighingBattery(entity.BarCode, entity.ResultFormerWeighing, weighing_time, entity.FormerWeighing, battery.Index, entity);
                    //    return;
                    //} 
                    weiging = GetWeiging(device, entity.BarCode);
                    if ((weiging == null || weiging < 20) && !_parameterStatic.DecideParameter.EnableEmptyRun)
                    {
                        RunLog($"[{entity.BarCode}] [{battery.Index}]号不稳定报警", MessageLevelType.警告);
                        alarm = true;
                    }
                    if (entity.FormerWeighing < 20)//小于20才赋新值
                        entity.FormerWeighing = weiging ?? 0;

                    if (!_parameterStatic.DecideParameter.EnableVariableInjection)
                        entity.NetWeight = entity.FormerWeighing;
                    //化成失液量
                    // if (_systemConfig.SCM.MainDeviceType == MainDeviceTypeEnum.二次注液)
                    //     entity.LossAfterFormation = entity.OneAfterWeighing - entity.FormerWeighing;

                    entity.ResultFormerWeighing = BeforeWeightRange_Check(entity);
                    if (entity.ResultFormerWeighing == ResultTypes.合格)
                    {
                        //if (!(_systemConfig.SCM.MainDeviceType == MainDeviceTypeEnum.一次注液) && _parameterStatic.DecideParameter.EnableVariableInjection) //变量注液
                        //{
                        //    string[] range = entity.RangeFluidRate.Split('-');
                        //    double standard = Convert.ToDouble(range[1]);
                        //    entity.TargetInjectionVolume = Math.Round(standard - (entity.FormerWeighing - entity.NetWeight), 2, MidpointRounding.AwayFromZero);
                        //}
                        //else
                        //{
                        //    entity.TargetInjectionVolume = _parameterStatic.RangeParameter.Quantitative;
                        //}

                        string[] range = entity.RangeFluidRate.Split('-');
                        double standard = Convert.ToDouble(range[1]);
                        if (!(_systemConfig.SCM.MainDeviceType == MainDeviceTypeEnum.一次注液) && _parameterStatic.DecideParameter.EnableVariableInjection) //变量注液
                        {
                            entity.LossAfterFormation = entity.OneAfterWeighing - entity.FormerWeighing;

                            entity.TargetInjectionVolume = Math.Round(standard - (entity.FormerWeighing - entity.NetWeight), 2, MidpointRounding.AwayFromZero);
                            RunLog($"当前二次注液，保液量：{standard}，二注前称重：{entity.FormerWeighing}，电池干重：{entity.NetWeight}注液量判定为：{entity.TargetInjectionVolume}");
                        }
                        else
                        {
                            RunLog($"当前一次注液，注液量直接取保液量：{standard}");
                            entity.TargetInjectionVolume = standard;
                        }
                        //if (!WriteInjectionVolume((float)(entity.TargetInjectionVolume<0?0: entity.TargetInjectionVolume), plc, battery.Address_Struct, context))
                        //{
                        //    entity.ResultFormerWeighing = ResultTypes.注液量写入失败;
                        //}
                    } 
                    RunLog($"-[前称重]条码{entity.BarCode}判断结果：{entity.ResultFormerWeighing} 总结果：{entity.ResultTotal}");

                    if (entity.ResultFormerWeighing != ResultTypes.合格 && (entity.ResultTotal == ResultTypes._|| entity.ResultTotal == ResultTypes.合格))
                    {
                        Interlocked.Increment(ref _weighingNG);
                        entity.ResultTotal = entity.ResultFormerWeighing;
                    }
                    else if (entity.ResultFormerWeighing == ResultTypes.合格 &&
                       (entity.ResultTotal == ResultTypes.称重偏轻 || entity.ResultTotal == ResultTypes.称重偏重 ||
                       entity.ResultTotal == ResultTypes.注液量写入失败))
                    {
                        entity.ResultTotal = entity.ResultFormerWeighing;
                    }

                    try
                    {
                        entity.Update();
                    }
                    catch (Exception ex)
                    {
                        RunLog($"-[{battery.Index}] 数据库保存异常：{ex}");
                    }
                    WriteResult(entity.BarCode, entity.ResultTotal, plc, battery.Address_Struct, context);
                    _homeStatic.AddBeforeWeighingBattery(entity.BarCode, entity.ResultFormerWeighing, weighing_time, entity.FormerWeighing, battery.Index, entity);
                });

                #region 图表统计
                _homeStatic.ChartData.NG_BeforeWeighin += _weighingNG;
                _homeStatic.ChartData.PassingRateInbound = Math.Round((double)(1 - ((_homeStatic.ChartData.NG_BeforeWeighin + _homeStatic.ChartData.NG_ScanCode) / _homeStatic.ChartData.Total_Inbound)), 4, MidpointRounding.AwayFromZero);
                #endregion

                if (alarm) { WriteCMD(1, plc, _systemConfig.IAddress.Alarm_BeforeWeighing); }
            }
            catch (Exception ex)
            {
                RunLog($"异常：{ex}");
            }
            return base.Handle(context);
        }
    }
}

